/*
 *@author: 陈旭光，Chen XuG,chenxvguang1991@163.com
 */

var can1=document.getElementById('can1');
var ctx1=can1.getContext('2d');
var can2=document.getElementById('can2');
var ctx2=can2.getContext('2d');
var cw=can1.width;//画布宽度
var ch=can1.height;//画布高度
var scoreSpan=document.getElementById('score');
var replay=document.getElementById('replay');
var score=null;
var cell=[];//方块数组
var index=4;
var bw=100;//方块宽度
var bh=100;//方块高度
var gameOn=false,gameover=false;
var gameOverArr=[['G','A','M','E'],['O','V','E','R']];//游戏结束，显示效果

window.onload=game;
document.onkeydown=playGame;
replay.onclick=replayGame;

function game(){
    gameover=false;
	init();
	newCell();
	newCell();
	loop();
}

function init(){
	ctx1.clearRect(0,0,cw,ch);
	ctx2.clearRect(0,0,cw,ch);
	score=new scoreObj;
	for(var i=0;i<index;i++){
		cell[i]=[];
		for(var j=0;j<index;j++){
			cell[i][j]={};
			cell[i][j].x=20+i*(bw+20);//方块x
			cell[i][j].y=20+j*(bh+20);//方块y
			cell[i][j].num=0;//方块内数字
			cell[i][j].show=false;
			cell[i][j].draw=new DrawObj(cell[i][j].x,cell[i][j].y,cell[i][j].num);
			ctx1.save();
			ctx1.fillStyle=color(cell[i][j].num);//根据数字判断color;
			ctx1.fillRect(cell[i][j].x,cell[i][j].y,bw,bh);
			ctx1.restore();
		}
	}
}

function loop(){
	window.requestAnimFrame(loop);
	for(var i=0;i<index;i++){
		for(var j=0;j<index;j++){
			cell[i][j].draw.newDraw();
			cell[i][j].draw.moveDraw();
		}
	}
	score.draw();
	gameOver();
}

function replayGame(){
	replay.style.display='none';
	game();
}

function gameOver(){
	if(gameover){
		for(var i=1;i<3;i++){
			for(var j=0;j<index;j++){
				ctx2.clearRect(cell[j][i].x,cell[j][i].y,bw,bh);
				ctx2.save();
				ctx2.fillStyle='rgba(240,240,240,.7)';
				ctx2.fillRect(cell[j][i].x,cell[j][i].y,bw,bh);
				ctx2.restore();
				ctx2.save();
				ctx2.font="80px  Arial";
				ctx2.textAlign="center";
				ctx2.fillText(gameOverArr[i-1][j],cell[j][i].x+50,cell[j][i].y+75);
				ctx2.restore();
			}
		}
		score.on=false;//游戏结束，分数不再增加
	}
}

function scoreObj(){
	this.m=0;
	this.n=0;
	this.score=0;
	this.on=true;
}
scoreObj.prototype.draw=function(){
	this.score=this.m*10+this.n*5;
	if(this.on){scoreSpan.innerHTML=this.score;}
}

function DrawObj(x,y){
	this.x=x;
	this.y=y;
	this.num=0;
	this.alphe=0;
	this.vy=0;
	this.vx=0;
	this.delatx=0;
	this.delaty=0;
	this.toNewDraw=false;
	this.toMoveDraw=false;
	this.ctx2Time=0;
}

DrawObj.prototype={
	newDraw:function(){
		if(this.toNewDraw&&this.num==2){
			this.ctx2Time++;
			this.alphe+=0.03;
			if(this.alphe>=1) {this.alphe=1;this.toNewDraw=false;};
			ctx2.clearRect(this.x,this.y,bw,bh);
			ctx2.save();
			ctx2.fillStyle='rgba(238,118,0,1)';
			ctx2.fillRect(this.x+50-this.alphe*50,this.y+50-this.alphe*50,bw*this.alphe,bh*this.alphe);
			ctx2.restore();
			if(this.alphe==1){
				ctx2.save();
				ctx2.font="80px  Arial";
				ctx2.textAlign="center";
				ctx2.fillText(this.num,this.x+50,this.y+75);
				ctx2.restore();	
				this.alphe=0;	
			}
		}
	},
	moveDraw:function(){
		if(this.toMoveDraw){
			//ctx2.clearRect(this.x+this.vx,this.y+this.vy,bw,bh);
			this.vx+=this.delatx;
			this.vy+=this.delaty;
			ctx2.save();
			ctx2.fillStyle=color(this.num);//根据数字判断color;
			ctx2.fillRect(this.x+this.vx,this.y+this.vy,bw,bh);
			ctx2.restore();
			
			if(this.num!=0){
				ctx2.save();
				ctx2.font=(this.num>100)?((this.num>1000)?("40px  Arial"):("50px  Arial")):("80px  Arial");
				ctx2.fillStyle=(this.num>100)?((this.num>1000)?("#FFFFFF"):("#9E9E9E")):("#262626");
				ctx2.textAlign="center";
				var y=(this.num>100)?((this.num>1000)?(60):(70)):(75);
				ctx2.fillText(this.num,this.x+50,this.y+y+this.vy);
				ctx2.restore();
			}

			if(this.vy==0&&this.vx==0) {this.toMoveDraw=false};
		}
	}
}

function newCell(){
	//判断方块值是否为0，并在0值方块中随机产生值为2方块
	var newC=[];
	for(var i=0;i<index;i++){
		for(var j=0;j<index;j++){
			if(cell[i][j].num==0) newC.push(cell[i][j]);
		}
	}
	if(newC.length){var _index=Math.floor(Math.random()*newC.length);
		newC[_index].num=2;
		newC[_index].draw.num=newC[_index].num;
		newC[_index].draw.toNewDraw=true;
	}
	else{	//当没有值为0的方块，且每个方块与四周方块值不同时，游戏结束。
		var over=0;
		for(var i=1;i<3;i++){
			for(var j=0;j<index;j++){
				if(cell[i][j].num==cell[i-1][j].num||cell[i][j].num==cell[i+1][j].num){
					over++;
				}
			}
		}


		for(var i=1;i<3;i++){
			for(var j=0;j<index;j++){
				if(cell[j][i].num==cell[j][i-1].num||cell[j][i].num==cell[j][i+1].num){
					over++;
				}
			}
		}

		if(over==0){gameover=true;replay.style.display='block'}
		else return;
	}


	
}

function playGame(e){
	
	e=e||window.event;
	if(e.keyCode==38) {up();newCell();}
	else if(e.keyCode==39) {right();newCell();}
	else if(e.keyCode==37) {left();newCell();}
	else if(e.keyCode==40) {down();newCell();}
	else return;
	score.m++;
	for(var i=0;i<index;i++){
		for(var j=0;j<index;j++){
			if(cell[i][j].num>score.n) score.n=cell[i][j].num;
		}
	}
}
//向上滑动方法
function up(){
	for(var i=0;i<index;i++){
		//从每列最下开始添加事件：如果值为0，则与其下面方块互换值
		for(var j=index-1;j>0;j--){
			if(cell[i][j-1].num==0&&cell[i][j].num!=0){
				cell[i][j-1].num=cell[i][j].num;
				cell[i][j].num=0;
				
				drawChange0(i,j,0,-1,0,0,0,0,0,120,0,-120);
			}
		}
		/*
		 *判断是否和上面方块值相等，若值相等则本方块值加倍，上方方块值清零。若上方方块值加倍，本方块值清零，
		 *方块可能继续与上方方块相加。
		 */
		 for(var j=index-1;j>0;j--){
		 	if(cell[i][j-1].num==0&&cell[i][j].num!=0){
		 		cell[i][j-1].num=cell[i][j].num;
		 		cell[i][j].num=0;
		 		
		 		drawChange0(i,j,0,-1,0,0,0,0,0,120,0,-120);
		 	}
		 }
		 for(var  j=0;j<index-1;j++){
		 	if(cell[i][j+1].num==cell[i][j].num&&cell[i][j].num!=0){
		 		cell[i][j].num=cell[i][j].num*2;
		 		cell[i][j+1].num=0;

		 		drawChange0(i,j,0,1,0,0,0,0,0,0,0,0);
		 	}
		 }

		//在方块相加结束后，会重新产生0值，再进行一次互换值
		for(var  j=index-1;j>0;j--){
			if(cell[i][j-1].num==0&&cell[i][j].num!=0){
				cell[i][j-1].num=cell[i][j].num;
				cell[i][j].num=0;
				
				drawChange0(i,j,0,-1,0,0,0,0,0,120,0,-120);
			}
			
		}

		for(var j=index-1;j>0;j--){
			if(cell[i][j-1].num==0&&cell[i][j].num!=0){
				cell[i][j-1].num=cell[i][j].num;
				cell[i][j].num=0;
				
				drawChange0(i,j,0,-1,0,0,0,0,0,120,0,-120);
			}
		}
	}
}
//向下滑动方法
function down(){
	for(var i=0;i<index;i++){
		for(var j=0;j<index-1;j++){
			if(cell[i][j+1].num==0&&cell[i][j].num!=0){
				cell[i][j+1].num=cell[i][j].num;
				cell[i][j].num=0;
				drawChange0(i,j,0,1,0,0,0,0,0,-120,0,120);
			}
		}

		for(var j=0;j<index-1;j++){
			if(cell[i][j+1].num==0&&cell[i][j].num!=0){
				cell[i][j+1].num=cell[i][j].num;
				cell[i][j].num=0;
				drawChange0(i,j,0,1,0,0,0,0,0,-120,0,120);
			}
		}

		for(var j=index-1;j>0;j--){
			if(cell[i][j-1].num==cell[i][j].num&&cell[i][j].num!=0){
				cell[i][j].num=cell[i][j].num*2;
				cell[i][j-1].num=0;

				drawChange0(i,j,0,-1,0,0,0,0,0,0,0,0);
			}
		}
		for(var j=0;j<index-1;j++){
			if(cell[i][j+1].num==0&&cell[i][j].num!=0){
				cell[i][j+1].num=cell[i][j].num;
				cell[i][j].num=0;
				
				drawChange0(i,j,0,1,0,0,0,0,0,-120,0,120);
			}
			
		}

		for(var j=0;j<index-1;j++){
			if(cell[i][j+1].num==0&&cell[i][j].num!=0){
				cell[i][j+1].num=cell[i][j].num;
				cell[i][j].num=0;
				drawChange0(i,j,0,1,0,0,0,0,0,-120,0,120);
			}
		}
	}
}
//向左滑动方法
function left(){
	for(var i=0;i<index;i++){
		for(var j=index-1;j>0;j--){
			if(cell[j-1][i].num==0&&cell[j][i].num!=0){
				cell[j-1][i].num=cell[j][i].num;
				cell[j][i].num=0;
				
				drawChange0(j,i,-1,0,0,0,0,0,120,0,-120,0);
			}
		}

		for(var j=index-1;j>0;j--){
			if(cell[j-1][i].num==0&&cell[j][i].num!=0){
				cell[j-1][i].num=cell[j][i].num;
				cell[j][i].num=0;
				
				drawChange0(j,i,-1,0,0,0,0,0,120,0,-120,0);
			}
		}

		for(var  j=0;j<index-1;j++){
			if(cell[j][i].num==cell[j+1][i].num&&cell[j][i].num!=0){
				cell[j][i].num=cell[j][i].num*2;
				cell[j+1][i].num=0;

				drawChange0(j,i,1,0,0,0,0,0,0,0,0,0);
			}
		}
		for(var  j=index-1;j>0;j--){
			if(cell[j-1][i].num==0&&cell[j][i].num!=0){
				cell[j-1][i].num=cell[j][i].num;
				cell[j][i].num=0;
				
				drawChange0(j,i,-1,0,0,0,0,0,120,0,-120,0);
			}
			
		}

		for(var j=index-1;j>0;j--){
			if(cell[j-1][i].num==0&&cell[j][i].num!=0){
				cell[j-1][i].num=cell[j][i].num;
				cell[j][i].num=0;
				
				drawChange0(j,i,-1,0,0,0,0,0,120,0,-120,0);
			}
		}
	}
}
//向右滑动方法
function right(){
	for(var i=0;i<index;i++){
		for(var j=0;j<index-1;j++){
			if(cell[j+1][i].num==0&&cell[j][i].num!=0){
				cell[j+1][i].num=cell[j][i].num;
				cell[j][i].num=0;
				drawChange0(j,i,1,0,0,0,0,0,-120,0,120,0);
			}
		}

		for(var j=0;j<index-1;j++){
			if(cell[j+1][i].num==0&&cell[j][i].num!=0){
				cell[j+1][i].num=cell[j][i].num;
				cell[j][i].num=0;
				drawChange0(j,i,1,0,0,0,0,0,-120,0,120,0);
			}
		}
		
		for(var  j=index-1;j>0;j--){
			if(cell[j][i].num==cell[j-1][i].num&&cell[j][i].num!=0){
				cell[j][i].num=cell[j][i].num*2;
				cell[j-1][i].num=0;

				drawChange0(j,i,-1,0,0,0,0,0,0,0,0,0);
			}
		}
		for(var j=0;j<index-1;j++){
			if(cell[j+1][i].num==0&&cell[j][i].num!=0){
				cell[j+1][i].num=cell[j][i].num;
				cell[j][i].num=0;
				drawChange0(j,i,1,0,0,0,0,0,-120,0,120,0);
			}
		}

		for(var j=0;j<index-1;j++){
			if(cell[j+1][i].num==0&&cell[j][i].num!=0){
				cell[j+1][i].num=cell[j][i].num;
				cell[j][i].num=0;
				drawChange0(j,i,1,0,0,0,0,0,-120,0,120,0);
			}
		}
		
	}
}

function drawChange0(i,j,m,n,vx0,vy0,dx0,dy0,vx1,vy1,dx1,dy1){
	cell[i][j].draw.num=cell[i][j].num;
	cell[i][j].draw.vx=vx0;
	cell[i][j].draw.vy=vy0;
	cell[i][j].draw.delatx=dx0;
	cell[i][j].draw.delaty=dy0;
	cell[i][j].draw.toMoveDraw=true;
	
	cell[i+m][j+n].draw.num=cell[i+m][j+n].num;
	cell[i+m][j+n].draw.vx=vx1;
	cell[i+m][j+n].draw.vy=vy1;
	cell[i+m][j+n].draw.delatx=dx1;
	cell[i+m][j+n].draw.delaty=dy1;
	cell[i+m][j+n].draw.toMoveDraw=true;
}

//根据方块内num获取方块颜色
function color(num){
	if(num==0){return '#CDB79E'}
	else if(num==2){return '#EE7600'}
	else if(num==4){return '#CDBE70'}
	else if(num==8){return '#CDCD00'}
	else if(num==16){return '#CDAD00'}
	else if(num==32){return '#CD9B1D'}
	else if(num==64){return '#CD853F'}
	else if(num==128){return '#CD6600'}
	else if(num==256){return '#CD5555'}
	else if(num==512){return '#CD3700'}
	else if(num==1024){return '#CD3333'}
	else if(num==2048){return '#CD0000'}
	}

window.requestAnimFrame = (function(){
	return  window.requestAnimationFrame       ||
	window.webkitRequestAnimationFrame ||
	window.mozRequestAnimationFrame    ||
	function( callback ){
		window.setTimeout(callback, 1000 / 60);
	};
})();